package org.vacoor.xqq.core.mod.receviver.impl;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.vacoor.nothing.common.util.Regexs;
import org.vacoor.xqq.core.Constants;
import org.vacoor.xqq.core.bean.Status;
import org.vacoor.xqq.core.http.HttpRequestor;
import org.vacoor.xqq.core.http.Request;
import org.vacoor.xqq.core.http.Response;
import org.vacoor.xqq.core.util.QQUtil;

import java.util.concurrent.Future;

/**
 * User: vacoor
 * Date: 10/21/13
 * Time: 10:00 AM
 */
public class CaptchaChecker implements org.vacoor.xqq.core.mod.CaptchaChecker {
    private static final Logger logger = LoggerFactory.getLogger(CaptchaChecker.class);

    // 登录指纹可以在这个html中找到 https://ui.ptlogin2.qq.com/cgi-bin/login?daid=164&target=self&richStyle=5&mibao_css=m_webqq&appid=1003903&enable_qlogin=0&no_verifyimg=1&s_url=http%3A%2F%2Fweb2.qq.com%2Floginproxy.html&f_url=loginerroralert&strong_login=1&login_state=10&ui=20130723001
    public static final String LOGIN_SIG = "";


    // ------------------------------------- //

    private String account; // 登录账户
    private long uin;
    private String verify;  // 验证码

    public CaptchaChecker(String account, String passwd, Status state) {
        this.account = account.toLowerCase(); // 不允许大写
    }

    /**
     * 安全性检查
     * 该方法校验是否需要输入验证码, 并接受用于加密密码的密钥
     * 响应有以下两种
     * 1. ptui_checkVC('0','!MII','\x00\x00\x00\x00\x83\xec\xb6\x7c');
     * 直接使用 '!MII' 作为验证码, 使用密钥'\x00\x00\x00\x00\x83\xec\xb6\x7c'(其实是QQ号码16进制) 加密
     * <p/>
     * 2. ptui_checkVC('1','80012das923jjsdfas3asds8891','\x00\x00\x00\x00\x83\xec\xb6\x7c');
     * 需要获取验证码后, 使用密钥进行加密
     *
     * @return 是否需要获取验证码
     */
    @Override
    public String check() {
        String verity = null;
        logger.info("发送校验信息..");

        Future<Response> f = HttpRequestor.getInstance().send(
                new Request(Constants.U_CHECK, Request.HttpMethod.GET)
                        .addParameter("uin", this.account)
                        .addParameter("appid", Constants.APP_ID)
                        .addParameter("login_sig", LOGIN_SIG)
                        .addParameter("u1", Constants.U_LOGIN_PROXY) //会自动转码不要转, 否则http client 2次转吗
                        .addParameter("r", Math.random()),
                null
        );

        try {
            Response resp = f.get();
            String s = resp.getContent().asString();
            /*
            String[][] grep = Regexs.grep(s, "ptui_checkVC\\('([0-9])','([^']*)','([^']{32})'\\)");
            // 正确解析结果
            if (1 == grep.length) {
                logger.debug("解析校验信息: {}", s);
                uin = QQUtil.decodeHexUin(grep[0][3]);

                if ("0".equals(grep[0][1])) {
                    CaptchaChecker.this.verify = grep[0][2];
                    verity = grep[0][2];
                }
            }
            */
            // update 2015 09 03
            String[][] grep = Regexs.grep(s, "ptui_checkVC\\('([0-9])','([^']*)','([^']{32})'(?:,'([^']*)','[0-9]'\\))?");
            if (1 == grep.length) {
                logger.debug("解析校验信息: {}", s);
                uin = QQUtil.decodeHexUin(grep[0][3]);

                // 验证码直接从下一个取得
                if ("0".equals(grep[0][1])) {
                    CaptchaChecker.this.verify = grep[0][2];
                    verity = grep[0][2];
                }
            } else {
                try {
                    uin = Long.valueOf(this.account);
                } catch (NumberFormatException ex) {}
            }
            System.out.println();

        } catch (Throwable e) {
            logger.error("解析校验信息出错.. ", e);
            System.exit(1);
        }
        return verity;
    }

    /**
     * 获取验证码
     *
     * @return 验证码字节
     */
    @Override
    public byte[] getCaptcha() {
        logger.info("获取验证码..");
        try {
            Response response = HttpRequestor.getInstance().send(
                    new Request(Constants.U_CAPTCHA, Request.HttpMethod.GET)
                            .addParameter("aid", Constants.APP_ID)
                            .addParameter("uin", this.account)
                            .addParameter("r", "" + Math.random()),
                    null
            ).get();
            return response.getContent().asBytes();
        } catch (Throwable e) {
            logger.error("获取验证码出错..");
            System.exit(1);
        }
        return new byte[0];
    }

    public String getAccount() {
        return account;
    }

    public void setAccount(String account) {
        this.account = account;
    }

    public long getUin() {
        return uin;
    }

    public void setUin(long uin) {
        this.uin = uin;
    }

    public String getVerify() {
        return verify;
    }

    public void setVerify(String verify) {
        this.verify = verify;
    }
}
